//go:build notest

package parser

import (
	"bufio"
	"os"
	"path/filepath"

	"gitee.com/u-language/u-language/ucom/ast"
	"gitee.com/u-language/u-language/ucom/check"
	"gitee.com/u-language/u-language/ucom/errcode"
	"gitee.com/u-language/u-language/ucom/internal/errutil"
	"gitee.com/u-language/u-language/ucom/internal/time"
	"gitee.com/u-language/u-language/ucom/lex"
)

func init() {
	notest = true
}

// openfileAndInfo 同时获取文件描述符和文件大小
func openfileAndInfo(path string) (*os.File, int64, []byte, error) {
	// 打开文件
	file, err := os.Open(path)
	if err != nil {
		return nil, 0, nil, err
	}
	Info, err := file.Stat()
	if err != nil {
		return nil, 0, nil, err
	}
	return file, Info.Size(), nil, err
}

// ParserFile 从一个代码文件创建ast树
//   - path是文件路径
//   - errctx是错误处理上下文
//   - IsCheck是控制是否进行语义检查
//   - Thread是控制是否并发
func ParserFile(path string, errctx *errcode.ErrCtx, IsCheck bool, ImportPackage *map[string]*ast.Package, Thread bool) (*ast.Tree, error) {
	file, size, _, err := openfileAndInfo(path) //获取文件描述符，文件大小
	if err != nil {
		return nil, err
	}
	var r *bufio.Reader = bufio.NewReaderSize(file, int(size))
	var t time.Time
	try_new_print_LexTime(&t)
	FT := lex.Lex2(path, r, errctx, false) //进行词法分析
	try_Print_Time(&t)
	try_print_FT(FT)
	if errctx.Errbol() { //如果词法分析有错误·
		return nil, errutil.NewErr2("错误", "词法分析有错")
	}
	try_new_print_AstTime(&t)
	tree := ast.NewTree(FT, errctx, ast.NewSbt(Thread), ImportPackage) //创建抽象语法树
	try_Print_Time(&t)
	try_print(tree)
	err = loadAllImport(filepath.Dir(path), tree.ImportTable, tree.ImportPackage, tree.ImportLoacl, Thread, errctx, tree.Sbt)
	if err != nil {
		return nil, err
	}
	if IsCheck { //如果要进行语义检查
		try_new_print_check(&t)
		check.CheckTree(tree, errctx, false)
		try_Print_Time(&t)
	}
	return tree, nil
}
